package com.k.kc.util;

import java.util.Arrays;
import java.util.Objects;

/**
 * 注意有些类型会包含前缀
 * 二进制前缀：0b 0B
 * 八进制前缀：0 0o 0O
 * 十进制前缀: 0
 * 十六进制前缀：0x 0X
 * @author kkk
 */
public class JinzhiKit {
    private final static int RADIX_2 = 2;
    private final static int RADIX_8 = 8;
    private final static int RADIX_10 = 10;
    private final static int RADIX_16 = 16;
    private final static int[] FORMAT_RADIX_ARR = {2,8,10,16};

    private static boolean isFormatRadixArr(int radix){
        return Arrays.stream(FORMAT_RADIX_ARR).anyMatch(itm->itm==radix);
    }

    /**
     * 校验是否符合 X进制数据
     * @param v value
     * @param radix 进制
     * @return value
     */
    private static String formatValue(String v, int radix){
        String result = v;
        if(RADIX_2 == radix){
            if(v.length()>2){
                if(v.toLowerCase().startsWith("0b")){
                    result = v.substring(2);
                }
            }
            for(int i=0;i<result.length();i++){
                char c = result.charAt(i);
                String cstr = String.valueOf(c);
                if(!("1".equals(cstr) || "0".equals(cstr))){
                    throw new RuntimeException("非法2进制数");
                }
            }
        } else if(RADIX_8 == radix){
            if(v.length()>2){
                if(v.toLowerCase().startsWith("0o")){
                    result = v.substring(2);
                }
            }
        }else if(RADIX_10 == radix){
            try{
                Integer.parseInt(v);
            }catch (Exception e){
                throw new RuntimeException("非法10进制数");
            }
            result = v;
        }else if(RADIX_16 == radix){
            if(v.length()>2){
                if(v.toLowerCase().startsWith("0x")){
                    result = v.substring(2);
                }
            }
        }
        return result;
    }

    /**
     * convertX method is easier then convert
     * @param v value
     * @param srcRadix srcRadix
     * @param destRadix destRadix
     * @return string
     */
    public static String convertX(String v,int srcRadix, int destRadix){
        Objects.requireNonNull(v,"input value must not be null or empty");
        if(!isFormatRadixArr(srcRadix)){
            throw new RuntimeException("不支持的 src radix");
        }
        if(!isFormatRadixArr(destRadix)){
            throw new RuntimeException("不支持的 dest radix");
        }
        if(srcRadix == destRadix){
            return v;
        }
        // resolve value contains prefix
        String result =formatValue(v,srcRadix);
        // 将 v 转换为 10进制
        long decimal = Long.parseLong(result,srcRadix);
        // 将v 转换为 其他进制
        switch (destRadix){
            case RADIX_2:
                result = Long.toBinaryString(decimal);
                break;
            case RADIX_8:
                result = Long.toOctalString(decimal);
                break;
            case RADIX_10:
                result = String.valueOf(decimal);
                break;
            case RADIX_16:
                result = Long.toHexString(decimal);
                break;
            default:
                result = v;
        }
        return result;
    }


    public static void main(String[] args) {
        //2 0b 0B
        String a = "0B1";
        //8 0 0o 0O
        int b = 06;
        //10 + -
        int c = +12;
        //16 0x 0X
        String d = "0x1a";
        int srcRadix = 10;
        /*for(int i=0;i<127;i++){
            String v10to10 = convertX(i+"",srcRadix,10);
            String v10to2 = convertX(i+"",srcRadix,2);
            String v10to8 = convertX(i+"",srcRadix,8);
            String v10to16 = convertX(i+"",srcRadix,16);
            System.out.println(v10to10+" | "+v10to2+" | "+v10to8+" | "+v10to16);
        }*/
        /*byte[] KEY_BYTE_ARR = {
                0x76, 0x12, 0x6D, 0x3E,
                0x64, 0x5C, 0x4B, 0x35,
                0x08, 0x17, 0x27, 0x2F,
                0x5E, 0x2A, 0x49, 0x57
        };
        for(int i=0;i<KEY_BYTE_ARR.length;i++){
            String t = convertX(KEY_BYTE_ARR[i]+"",16,10);
            System.out.println(t);
            System.out.println(KEY_BYTE_ARR[i]);
            System.out.println("=============");
        }*/
        System.out.println(convertX("-113",10,2));
        System.out.println(convertX("111010110111100110100010101",2,10));
        // byte 有符号，无符号
        // 值范围：[-128 127] 长度范围256
        // 值范围：[0,255]    长度范围256
        byte mba = (byte) 0x8f;
        System.out.println(mba);
        System.out.println(convertX("325",10,16));
    }
}
